#include "stdafx.h"

#include <MobileDgn/MobileDgnApplication.h>
#include <DgnPlatform/DgnPlatformApi.h>
#include <DgnPlatform/DgnPlatform.h>
#include <DgnView\AccuSnap.h>
#include <DgnView/IRedraw.h>

#include "TestElevationTool.h"

USING_NAMESPACE_BENTLEY
USING_NAMESPACE_BENTLEY_DGNPLATFORM
USING_NAMESPACE_BENTLEY_MOBILEDGN
USING_NAMESPACE_PBBIM_CORE

//=======================================================================================
// @bsiclass                                               Y.Dong          1/2015
//=======================================================================================
class ElevationCreator
{
private:
    CArray<DSegment3d, DSegment3d&> &m_resultSegs;
    CArray<DPoint3d, DPoint3d&> &m_inters;

public:
    //---------------------------------------------------------------------------------------
    // @bsimethod                                              Y.Dong          1/2015
    //---------------------------------------------------------------------------------------
    ElevationCreator(CArray<DSegment3d, DSegment3d&> &segs, CArray<DPoint3d, DPoint3d&> &inters) : m_resultSegs(segs), 
        m_inters(inters)
    {
    }

    //---------------------------------------------------------------------------------------
    // @bsimethod                                              Y.Dong          1/2015
    //---------------------------------------------------------------------------------------
    StatusInt CreateElevationGraphics(PhysicalGraphicsPtr& graphicsPtr)
    {
        if (m_resultSegs.GetSize() == 0)
            return ERROR;

        DgnProjectPtr project = MobileDgnApplication::App().Project();
        DgnModelId modelId = ModelUtil::GetDefaultModelId(*project);
        DgnModelP dgnModel = project->Models().GetModelById(modelId);
        if (NULL == dgnModel)
            return ERROR;

        // create the graphics container
        graphicsPtr = dgnModel->CreatePhysicalGraphics();
        if (!graphicsPtr.IsValid())
            return ERROR;

        // create geometry
        for (int i = 0; i < m_resultSegs.GetSize(); i++)
        {
            DSegment3d seg = m_resultSegs[i];

            DPoint3d ps, pe;
            seg.GetStartPoint(ps);
            seg.GetEndPoint(pe);

            ps.z = 0;
            pe.z = 0;

            PointArray  points;
            points.push_back(ps);
            points.push_back(pe);

            CurveVectorPtr curveVectorPtr = CurveVector::CreateLinear(points);
            if (!curveVectorPtr.IsValid())
                return ERROR;

            // add geometry to the graphics container
            Symbology symb;

            IntColorDef intColor(255, 168, 0);
            DgnColors& projectColors = project->Colors();

            symb.color = projectColors.GetElementColor(intColor, NULL, NULL, true);
            symb.weight = 1;

            if (BSISUCCESS != graphicsPtr->AddCurveVector(*curveVectorPtr, symb))
                return ERROR;
        }

        for (int i = 0; i < m_inters.GetSize(); i++)
        {
            DPoint3d centerPoint = m_inters[i];
            centerPoint.z = 0;
            double radius = 2;

            DEllipse3d ellipse;
            ellipse.Init(centerPoint.x, centerPoint.y, centerPoint.z, radius, 0.0, 0.0, 0.0, radius, 0.0, 0.0, msGeomConst_2pi);

            ICurvePrimitivePtr arc = ICurvePrimitive::CreateArc(ellipse);

            IntColorDef intColor(255, 0, 0);

            DgnColors& projectColors = project->Colors();

            Symbology symb;
            symb.color = projectColors.GetElementColor(intColor, NULL, NULL, true);
            //symb.style = 2;
            symb.weight = 2;

            graphicsPtr->AddCurvePrimitive(*arc, symb);
        }

        // tell container that adds are complete so the element can be generated and range calculated
        if (BSISUCCESS != graphicsPtr->Finish())
            return ERROR;

        return SUCCESS;
    }

};//ElevationCreator

/*---------------------------------------------------------------------------------**//**
* @bsimethod                                   Y.Dong                       1/2015
+---------------+---------------+---------------+---------------+---------------+------*/
TestElevationTool::TestElevationTool () : DgnPrimitiveTool (0)
{
}

/*---------------------------------------------------------------------------------**//**
* @bsimethod                                   Y.Dong                       1/2015
+---------------+---------------+---------------+---------------+---------------+------*/
TestElevationTool::~TestElevationTool ()
{
}

/*---------------------------------------------------------------------------------**//**
* @bsimethod                                   Y.Dong                       1/2015
+---------------+---------------+---------------+---------------+---------------+------*/
void TestElevationTool::_OnRestartTool ()
{
    TestElevationTool* tool = new TestElevationTool ();
    tool->InstallTool ();
}

/*---------------------------------------------------------------------------------**//**
* @bsimethod                                   Y.Dong                       1/2015
+---------------+---------------+---------------+---------------+---------------+------*/
bool TestElevationTool::_OnDataButton (DgnButtonEventCP ev)
{
    HitPathCP hitPathCP = ElementLocateManager::GetManager().DoLocateHitPath(NULL, NULL, true, ev->GetPoint(), ev->GetViewport(), 0);
    if (hitPathCP && hitPathCP->GetHeadElem())
    {
        EditElementHandle eeh(hitPathCP->GetHeadElem());
        BentleyApi::BeSQLite::EC::ECInstanceKey itemKey;

        if (DgnECPersistence::GetPrimaryInstanceOnElement(itemKey, eeh))
        {
            DgnProjectPtr project = MobileDgnApplication::App().Project();

            CArray<DSegment3d, DSegment3d&> segsLeft, segsRight;
            CArray<DPoint3d, DPoint3d&> intList;

            //FuncCalWallLineJoin::main(itemKey,segsLeft,segsRight,intList);

            PhysicalGraphicsPtr graphicsPtr;
            if (SUCCESS == ElevationCreator(segsRight, intList).CreateElevationGraphics(graphicsPtr))
            {
                graphicsPtr->Save();
                _CloseCurrentTxn();
            }

            // commit the transaction
            _CloseCurrentTxn();
        }
    }

    _OnReinitialize();

    return true;
}

/*---------------------------------------------------------------------------------**//**
* @bsimethod                                   Y.Dong                       1/2015
+---------------+---------------+---------------+---------------+---------------+------*/
bool TestElevationTool::_OnResetButton (DgnButtonEventCP ev)
{
    _OnReinitialize ();

    return true;
}

/*---------------------------------------------------------------------------------**//**
* @bsimethod                                   Y.Dong                       1/2015
+---------------+---------------+---------------+---------------+---------------+------*/
void TestElevationTool::_OnDynamicFrame (DgnButtonEventCP ev)
{
    //PhysicalGraphicsPtr circleGraphics;
    //if (SUCCESS != CircleCreator (m_points).CreateCircleGraphics (circleGraphics) || !circleGraphics.IsValid ())
    //{
    //    m_points.pop_back ();
    //    return;
    //}

    RedrawElems redrawElems;
    redrawElems.SetDrawMode (DgnDrawMode::TempDraw);
    redrawElems.SetDrawPurpose (DrawPurpose::Dynamics);
    if (NULL != ev && NULL != ev->GetViewport ())
        redrawElems.SetDynamicsViews (IViewManager::GetActiveViewSet (), ev->GetViewport ());
    else
        redrawElems.SetViews (IViewManager::GetActiveViewSet (), 0xffff);

    //redrawElems.DoRedraw (circleGraphics->GetElementHandleR ());

    //m_points.pop_back ();
}

//---------------------------------------------------------------------------------------
// @bsimethod                                               Y.Dong          1/2015
//---------------------------------------------------------------------------------------
void TestElevationTool::_OnPostInstall ()
{
    T_Super::_OnPostInstall ();

    AccuSnap::GetInstance ().EnableSnap (true);

    IViewManager::GetManager ().SetViewCursor (IViewManager::GetManager ().GetCursor (IViewManager::CURSOR_Arrow));

    MobileDgnApplication::App ().SendMessageToUiThread (PBBim_MESSAGE_ToolPrompt, "Please Select a wall");
}

//---------------------------------------------------------------------------------------
// @bsimethod                                                   Y.Dong          1/2015
//---------------------------------------------------------------------------------------
RegTool(PBBIM_TEST_ELEVATION, TestElevationTool);
